import store from "@/store";
import request from "@/utils/request";

export function mountManualTriggerGuide(routePath, checkPath = true) {
  const manualTriggerGuideUser = store.getters.manualTriggerGuideUser;
  if (Array.isArray(manualTriggerGuideUser)) {
    const guidleUser = manualTriggerGuideUser.find((item) => {
      return item.modulePath === routePath;
    });
    const btnElement = document.getElementById("suspendBtn");
    if (btnElement) {
      document.getElementById("app").removeChild(btnElement);
    }
    if (guidleUser) {
      const btn = document.createElement("input");
      btn.setAttribute("type", "button");
      btn.setAttribute("value", "启动向导");
      btn.setAttribute("id", "suspendBtn");
      btn.setAttribute("className", "suspend-btn");
      btn.setAttribute(
        "style",
        "position: absolute;top: 260px;right:36px;z-index: 100;"
      );
      btn.onclick = function () {
        if (checkPath) {
          throw new Error(
            "The wizard was not found at the current path[" + routePath + "]..."
          );
        }
        buildIntroJs(guidleUser);
      };
      document.getElementById("app").appendChild(btn);
    }
  }
}

export function loadManualTriggerGuide(routePath, checkPath = false) {
  buildIntroJsHandle(
    routePath,
    store.getters.manualTriggerGuideUser,
    checkPath
  );
}

export function loadAutoTriggerGuide(routePath, checkPath = false) {
  buildIntroJsHandle(routePath, store.getters.autoTriggerGuideUser, checkPath);
}

function buildIntroJsHandle(routePath, guideUser, checkPath = false) {
  if (Array.isArray(guideUser)) {
    // 这里只会跑第一个向导，至于要不要全跑，待议...
    const guide = guideUser.find((item) => {
      return item.modulePath === routePath;
    });
    if (guide) {
      buildIntroJs(guide);
    } else if (checkPath) {
      throw new Error(
        "The wizard was not found at the current path[" + routePath + "]..."
      );
    }
  }
}

function buildIntroJs(guide) {
  if (guide) {
    const {
      guideAttr,
      guideType,
      steps,
      hints,
      guideEvents,
      triggerType,
      isTrigger,
      guideId
    } = guide;
    const introJsInstance = introJs();
    introJsInstance.setOptions(
      Object.assign(
        guideType === "hints" ?
        {
          hints: hints,
        } :
        {
          steps: filterInvalidAttr(steps),
        },
        guideAttr
      )
    );
    setIntroJsEvents(
      introJsInstance,
      guideEvents,
      triggerType,
      isTrigger,
      steps,
      guideId
    );

    guideType === "hints" ?
      introJsInstance.addHints() :
      introJsInstance.start();
  }
}

function setIntroJsEvents(
  introJsInstance,
  guideEvents,
  triggerType,
  isTrigger,
  steps,
  guideId
) {
  const stepsMap = new Map();
  if (Array.isArray(steps)) {
    steps.map((item, index) => {
      stepsMap.set(index, item.stepEvent);
    });
  }

  executeEvent(guideEvents, "onInit");
  introJsInstance.onafterchange(() => {
    executeEvent(
      stepsMap.get(introJsInstance.currentStep()),
      "onafterchange",
      guideEvents,
      "onafterchange"
    );
  });
  introJsInstance.onbeforechange(() => {
    executeEvent(
      stepsMap.get(introJsInstance.currentStep()),
      "onbeforechange",
      guideEvents,
      "onbeforechange"
    );
  });
  introJsInstance.onchange(() => {
    executeEvent(
      stepsMap.get(introJsInstance.currentStep()),
      "onchange",
      guideEvents,
      "onchange"
    );
  });
  introJsInstance.onbeforeexit(() => {
    executeEvent(null, null, guideEvents, "onbeforechange");
  });
  introJsInstance.oncomplete(() => {
    executeEvent(null, null, guideEvents, "oncomplete");
    if (triggerType === "auto" && !isTrigger) {
      triggerCurrGuide(guideId);
    }
  });
  introJsInstance.onexit(() => {
    executeEvent(null, null, guideEvents, "onexit");
  });
  introJsInstance.onhintclick(() => {
    executeEvent(null, null, guideEvents, "onhintclick");
  });
  introJsInstance.onhintclose(() => {
    executeEvent(null, null, guideEvents, "onhintclose");
  });
  introJsInstance.onhintsadded(() => {
    executeEvent(null, null, guideEvents, "onhintsadded");
  });
  introJsInstance.onskip(() => {
    executeEvent(null, null, guideEvents, "onskip");
  });
}

function executeEvent(itemEvent, itemEventKey, globalEvent, globalEventKey) {
  if (itemEvent && itemEvent[itemEventKey]) {
    eval(itemEvent[itemEventKey]);
  }
  if (globalEvent && globalEvent[globalEventKey]) {
    eval(globalEvent[globalEventKey]);
  }
}

function triggerCurrGuide(guideId) {
  request({
      url: "/system/guideLog/save",
      method: "post",
      data: {
        pageAction: "create",
        model: {
          guideId: guideId,
        },
      },
    })
    .then((res) => {
      if (res && res.success) {
        // 重新拉取向导信息
        store.dispatch("loadCurrNotTriggerGuide");
      } else {
        console.error(res.message || "triggerCurrGuide error.");
      }
    })
    .catch((err) => {
      console.error("triggerCurrGuide error：", err);
    });
}

function filterInvalidAttr(arr, excludeKey = ["stepEvent"]) {
  const array = [];
  arr.forEach((item) => {
    const validObj = {};
    for (let key in item) {
      if (!excludeKey.includes(key)) {
        if (typeof item[key] === "string" && item[key].trim().length > 0) {
          validObj[key] = item[key];
          continue;
        }
        if (item[key]) {
          validObj[key] = item[key];
        }
      }
    }
    if (validObj.element && window.jQuery) {
      validObj.element = (window.jQuery(validObj.element) || [validObj.element])[0];
    }
    array.push(validObj);
  });
  return array;
}
